from codec import util
from os import system
from typing import Tuple, Union, Generator, Callable
from detect import color, speech


class Media:
    '''Imported video with edits.

    ## Attributes:

    filepath: str

    method: str

    marks: list[dict[str, Union[str, float]]]

    clips: list[dict[str, float]]
        A list of dict, each of element of which contains only 2 keys, namely
        "start" and "end", representing the start second and end second of
        the preserved clip respectively.\\
        Example:

        [
            {
                "start": 5.14,
                "end": 6
            },
            {
                "start": 10.01,
                "end": 19.19
            }
        ]
    
    goodRGB: tuple[int, int, int]
        RGB for good mark if color detection is used.

    badRGB: tuple[int, int, int]
        RGB for bad mark if color detection is used.
    '''

    def __init__(self, filepath: str, method: str):
        self.filepath: str = filepath
        self.method: str = method
        self.marks: list[dict[str, Union[str, float]]] = []
        self.clips: list[dict[str, float]] = [{"None": 0}]
        self.goodRGB: Tuple[int, int, int] = (0, 0, 0)
        self.badRGB: Tuple[int, int, int] = (0, 0, 0)

    def getDetectGen(self, method) -> Callable[[str], Generator[Union[int, list[dict[str, Union[str, float]]]], None, None]]:
        if method == 'Color':
            return lambda filepath: color.detect_color(filepath, self.goodRGB, self.badRGB)
        else:
            return speech.detect

    def detect(self):
        for i in self.getDetectGen(self.method)(self.filepath):
            if isinstance(i, list):
                self.marks = i
            else:
                yield i

    def getMarks(self) -> list[dict[str, Union[str, float]]]:
        return self.marks

    def getClips(self) -> list[dict[str, float]]:
        if "None" in self.clips[0]:
            self.clips = util.m2c(self.getMarks())
        #print("get",self.clips)
        return self.clips

    def export(self, outputPath: str, inOne: bool) -> None:
        '''Exports preserved clips to outputPath with the same quality of source.

        ## Parameters

        outputPath: str

        inOne: bool

        ## Raises

        FileNotFoundError: No such file or directory: 'swap.json'
        '''
        # self.sync()
        system(f'mkdir {outputPath}')
        for i in range(len(self.clips)):
            system((
                f'ffmpeg '
                f'-ss {self.clips[i]["start"]} '
                f'-t {self.clips[i]["end"] - self.clips[i]["start"]} '
                f'-accurate_seek '
                f'-i "{self.filepath}" '
                f'"{outputPath}/{i}.mp4"'
            ))
        if inOne:
            print(outputPath)
            with open(f'{outputPath}/filelist.txt', 'w') as file:
                file.writelines([
                    f"file 'file:{outputPath}/{i}.mp4'\n"
                    for i in range(len(self.clips))
                ])
            print(
                f'ffmpeg -safe 0 -f concat -i "{outputPath}/filelist.txt" -c copy "{outputPath}/output.mp4"'
            )
            system(
                f'ffmpeg -safe 0 -f concat -i "{outputPath}/filelist.txt" -c copy "{outputPath}/output.mp4"'
            )
            tmp = outputPath.replace("/", "\\")
            print(tmp)
            system(f'del "{tmp}\\filelist.txt"')
            for i in range(len(self.clips)):
                print(f'del "{tmp}\\{i}.mp4"')
                system(f'del "{tmp}\\{i}.mp4"')
